package com.huarui.returned.service;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONArray;
import net.sf.json.JSONNull;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.ewaf.framework.exception.BizException;
import org.ewaf.framework.model.ListModel;
import org.ewaf.framework.service.BaseService;
import org.ewaf.framework.task.Engine;
import org.ewaf.framework.task.EngineAccess;
import org.ewaf.framework.task.Handler;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;

import com.huarui.button.EngineTypeEnum;
import com.huarui.code.dao.ICodeGenericDao;
import com.huarui.code.model.CodeGeneric;
import com.huarui.dictionary.DictionaryEnum;
import com.huarui.inventory.dao.IInventoryDao;
import com.huarui.inventory.error.InventoryErrorEnum;
import com.huarui.inventory.model.Inventory;
import com.huarui.partner.dao.IPartnerDao;
import com.huarui.partner.model.Partner;
import com.huarui.payable.dao.IPayableDao;
import com.huarui.payable.model.Payable;
import com.huarui.quotation.service.QuotationService;
import com.huarui.returned.dao.IReturnedDao;
import com.huarui.returned.dao.IReturnedItemDao;
import com.huarui.returned.model.Returned;
import com.huarui.returned.model.ReturnedButtonEnum;
import com.huarui.returned.model.ReturnedItem;
import com.huarui.returned.model.ReturnedModel;
import com.huarui.user.dao.IUserDao;
import com.huarui.user.model.SessionMessage;
import com.huarui.user.model.User;
import com.huarui.user.security.UserHolder;
import com.huarui.util.ConstantUtil;
import com.huarui.util.JsonUtil;

public class ReturnedService extends BaseService {

	private IReturnedItemDao returnedItemDao;
	private ICodeGenericDao codeGenericDao;
	private IInventoryDao inventoryDao;
	private IPartnerDao partnerDao;
	private IPayableDao payableDao;
	private IUserDao userDao;
	private QuotationService quotationService;
	private IReturnedDao getDao() {
		return (IReturnedDao) dao;
	}
    private EngineAccess engineAccess;
    private TransactionTemplate transactionTemplate;
    
	
	/**
	 * 查询该公司下所有处于草稿或已提交状态下的退货单
	 * @param map
	 * @return
	 */
	public List<Returned> getReturnedByCompanyId(Integer companyId){
		Map<String,Object> map = new HashMap<String,Object>();
		map.put(ConstantUtil.PARAM_OF_COMPANYID, companyId);
		List<String> statusList = new ArrayList<String>();
		statusList.add(Returned.STATUS_DRAFT);
		statusList.add(Returned.STATUS_SUBMIT);
		map.put(ConstantUtil.PARAM_OF_STATUSLIST, statusList);
		return getDao().getReturnedByConditions(map);
	}

	@SuppressWarnings("unchecked")
	public List<ReturnedModel> getReturnedByComplexConditons(Map map){
		return getDao().getReturnedByComplexConditons(map);
	}
	/**
	 * 根据codeOfBuyer查询该公司下的退货单
	 * @param companyId
	 * @param codeOfBuyer
	 * @return
	 */
	public ReturnedModel getReturnedByCodeOfBuyer(Integer companyId,String codeOfBuyer,String varGroup){
		Map<String,Object> map = new HashMap<String,Object>();
		map.put(ConstantUtil.PARAM_OF_COMPANYID, companyId);
	   	map.put(ConstantUtil.PARAM_OF_CODEOFBUYER, codeOfBuyer);
	   	map.put(ConstantUtil.PARAM_OF_VARGROUP, varGroup);
        List<ReturnedModel> rms = getReturnedByComplexConditons(map);	
        if(rms != null){
        	return rms.get(0);
        }
        return null;
	}
	/**
	 * 根据退货单Id查询退货单明细
	 * @param returnedId
	 * @return
	 */
	public List<Map<String,String>> getReturnedItemsByReturnedId(Integer returnedId){
		return returnedItemDao.getReturnedItemsByReturnedId(returnedId);
		
	}
	/**
	 * 根据状态，得到按钮
	 * @param status
	 * @param currentorId
	 * @param userId
	 * @return {"isOwner":xxxxx,"buttons":[{xxx},{xxxx}...]}
	 */
	public JSONObject generateButtonsByStatus(String status, Integer currentorId,Integer userId) {
		//id，据此获得按钮
		String id = null;
		//判断单据所有者
		boolean isOwner = false;
		//按钮列表
		
		//判断是否当前所有者打开单据
		if(currentorId != null && currentorId.equals(userId)){	
			isOwner = true;
		}
		if(status.equals(Returned.STATUS_DRAFT)){
			if(isOwner){
				 id=ReturnedButtonEnum.STATUS_OF_DRAFTBYOWNER.getType();				
			}else{
				 id = ReturnedButtonEnum.STATUS_OF_DRAFTBYOTHER.getType();
			}
		}else if(status.equals(Returned.STATUS_SUBMIT)){
			if(isOwner){
				id = ReturnedButtonEnum.STATUS_OF_SUBMITBYOWNER.getType();
			}else{
				id= ReturnedButtonEnum.STATUS_OF_SUBMITBYOTHER.getType();
			}
		}else if(status.equals(Returned.STATUS_RETURNED)){
			id = ReturnedButtonEnum.STATUS_OF_RETURNED.getType();
		}else if(status.equals(Returned.STATUS_TO_CREATE)){
			id = ReturnedButtonEnum.STATUS_OF_TOCREATE.getType();			
		}
		JSONArray buttonArray  = getButtons(id);
		JSONObject buttonObj = new JSONObject();
		buttonObj.put(ConstantUtil.JSON_OF_ISOWNER, isOwner);
		buttonObj.put(ConstantUtil.JSON_OF_BUTTONS, buttonArray);		
		return buttonObj;
	}
    /**
     * 根据状态获得按钮
     * @param id
     * @return
     */
    private JSONArray getButtons(String id) {
    	Engine engine = engineAccess.getEngine(EngineTypeEnum.ENGINE_TYPE_RETURNED.getType());
	    List<Handler> handlers=engine.getHandlers(id);
	    JSONArray handlerObj = JSONArray.fromObject(handlers);	    
	    return handlerObj;
    }

	public EngineAccess getEngineAccess() {
		return engineAccess;
	}

	public void setEngineAccess(EngineAccess engineAccess) {
		this.engineAccess = engineAccess;
	}
    /**
     * 草稿状态操作
     * 返回json字符串:{'success':true,'returned':{xxxxx},'returnedItems':[{xxxx},{xxxx}....],'msg':{'confirm'/'alert':xxxxx},'buttons':{'isOwner':true/false,'buttons':{xxxx}}}
     * @param queryParam
     * @return {'success':true,'returned':{xxxxx},'returnedItems':[{xxxx},{xxxx}....],'msg':{'confirm'/'alert':xxxxx},'buttons':{'isOwner':true/false,'buttons':{xxxx}}} or {"success":false,"msg":"xxxxx"}
     */
	public JSONObject backupDraft(String queryParam) {
		final SessionMessage sessionMessage = UserHolder.getCurrentSessionMessage();
		final JSONObject returnedObj = JSONObject.fromObject(queryParam);		
		//保存数据
	    Object result = transactionTemplate.execute(new TransactionCallback() {
	    	
			@SuppressWarnings("unchecked")
			@Override
			public Object doInTransaction(TransactionStatus status) {
				Returned returned = generateReturned(returnedObj);
				Map<String,Object> returnedItemsObject = generateReturnedItem(returnedObj);
				List<Integer> deleteItemIds = generateDeleteItemIds(returnedObj);
				List<ReturnedItem> modifyItems = (List<ReturnedItem>) returnedItemsObject.get(ConstantUtil.KEY_OF_MODIFYITEMS);
				List<ReturnedItem> addItems = (List<ReturnedItem>) returnedItemsObject.get(ConstantUtil.KEY_OF_ADDITEMS);
				BigDecimal amount = (BigDecimal) returnedItemsObject.get(ConstantUtil.KEY_OF_AMOUNT);
		    	returned.setAmount(amount);
		    	returned.setStatus(Returned.STATUS_DRAFT);
		    	JSONObject response = new JSONObject();
				if(returned.getId() == null){
			    	//初次操作该单据
			    	insertReturned(sessionMessage, returned);			 		    			    	
			    }else{
			    	//修改单据,备份该表单
			    	response = checkCurrentorBeforeUpdate(sessionMessage, returned);
			    	if(response != null){
			    		return response;
			    	}
			    	getDao().update(returned);
			    	if (modifyItems != null && modifyItems.size()>0) {
						returnedItemDao.batchUpdateReturnedItems(modifyItems);
					}					
					if (deleteItemIds != null && deleteItemIds.size()>0) {
						batchDeleteItems(returned, deleteItemIds);
					}
			    }
				if (addItems != null && addItems.size()>0) {
					addItems = setAddItemsReturnedId(addItems,returned);
					returnedItemDao.batchInsertReturnedItems(addItems);
				}
				//页面返回信息
				response = generateResponse(sessionMessage, returned);				
				return response;
			}		
		});	    		
		return  (JSONObject) result;
		
	}

	
	/**
	 * 提交、备份退货单
	 * 返回json字符串:{'success':true,'returned':{xxxxx},'returnedItems':[{xxxx},{xxxx}....],'msg':{'confirm'/'alert':xxxxx},'buttons':{'isOwner':true/false,'buttons':{xxxx}}}
	 * @param queryParam
	 * @return {'success':true,'returned':{xxxxx},'returnedItems':[{xxxx},{xxxx}....],'msg':{'confirm'/'alert':xxxxx},'buttons':{'isOwner':true/false,'buttons':{xxxx}}}
	 * or {"success":false,"msg":"xxxxx"}
	 */
	public JSONObject backupSubmit(String queryParam){
		final SessionMessage sessionMessage = UserHolder.getCurrentSessionMessage();
		final JSONObject returnedObj = JSONObject.fromObject(queryParam);	
		//保存数据
		Object result = transactionTemplate.execute(new TransactionCallback() {			
			@SuppressWarnings("unchecked")
			@Override
			public Object doInTransaction(TransactionStatus status) {
				Returned returned = generateReturned(returnedObj);
				Map<String,Object> returnedItemsObject = generateReturnedItem(returnedObj);
				List<Integer> deleteItemIds = generateDeleteItemIds(returnedObj);
				List<ReturnedItem> modifyItems = (List<ReturnedItem>) returnedItemsObject.get(ConstantUtil.KEY_OF_MODIFYITEMS);
				List<ReturnedItem> addItems = (List<ReturnedItem>) returnedItemsObject.get(ConstantUtil.KEY_OF_ADDITEMS);
				BigDecimal amount = (BigDecimal) returnedItemsObject.get(ConstantUtil.KEY_OF_AMOUNT);
		    	returned.setAmount(amount);
		    	returned.setStatus(Returned.STATUS_SUBMIT);
		    	returned.setSubmitter(sessionMessage.getUserId());		    	
		    	JSONObject response = new JSONObject();
				if(returned.getId() == null){
					//初次操作该表单，直接提交单据至仓库
					insertReturned(sessionMessage, returned);			    	
				}else{
					response = checkCurrentorBeforeUpdate(sessionMessage, returned);
			    	if(response != null){
			    		return response;
			    	}
					//由草稿提交单据或修改已提交的单据，再次备份该表单
					getDao().update(returned);
					if (modifyItems !=null && modifyItems.size()>0) {
						returnedItemDao.batchUpdateReturnedItems(modifyItems);
					}					
					if (deleteItemIds != null && deleteItemIds.size()>0) {
						batchDeleteItems(returned, deleteItemIds);
					}
				}
				if (addItems != null && addItems.size()>0) {
					addItems = setAddItemsReturnedId(addItems,returned);
					returnedItemDao.batchInsertReturnedItems(addItems);
				}
				//页面返回信息
			     response = generateResponse(sessionMessage, returned);			    
				 return response;
			}
		});	    	
		return  (JSONObject) result;
	}
	
	
	/**
	 * 退货完成
	  * 返回json字符串:{'success':true,'returned':{xxxxx},'returnedItems':[{xxxx},{xxxx}....],'msg':{'confirm'/'alert':xxxxx},'buttons':{'isOwner':true/false,'buttons':{xxxx}}}
	 * @param queryParam
	 * @return {'success':true,'returned':{xxxxx},'returnedItems':[{xxxx},{xxxx}....],'msg':{'confirm'/'alert':xxxxx},'buttons':{'isOwner':true/false,'buttons':{xxxx}}}
	 * or {"success":false,"msg":"xxxxx"}
	 */
	public JSONObject backupReturned(String queryParam){
		final SessionMessage sessionMessage = UserHolder.getCurrentSessionMessage();
		final JSONObject returnedObj = JSONObject.fromObject(queryParam);
		
		Object result = transactionTemplate.execute(new TransactionCallback() {
			@SuppressWarnings("unchecked")
			@Override
			public Object doInTransaction(TransactionStatus status) {
				Returned returned = generateReturned(returnedObj);
				Map<String,Object> returnedItemsObject = generateReturnedItem(returnedObj);
				List<Integer> deleteItemIds = generateDeleteItemIds(returnedObj);
				List<ReturnedItem> modifyItems = (List<ReturnedItem>) returnedItemsObject.get(ConstantUtil.KEY_OF_MODIFYITEMS);
				List<ReturnedItem> addItems = (List<ReturnedItem>) returnedItemsObject.get(ConstantUtil.KEY_OF_ADDITEMS);
				BigDecimal amount = (BigDecimal) returnedItemsObject.get(ConstantUtil.KEY_OF_AMOUNT);
		    	
		    	JSONObject response = new JSONObject();
				if(returned.getId() == null){
					//初次操作该表单,直接退货
					setReturnedAtDeposite(sessionMessage, returned, amount);
					insertReturned(sessionMessage, returned);	    	
				}else{
					response = checkCurrentorBeforeUpdate(sessionMessage, returned);
			    	if(response != null){
			    		return response;
			    	}
			    	setReturnedAtDeposite(sessionMessage, returned, amount);
					//由提交单修改单据，再退货
					getDao().update(returned);
					if (modifyItems != null && modifyItems.size()>0) {
						returnedItemDao.batchUpdateReturnedItems(modifyItems);
					}								
					if (deleteItemIds != null && deleteItemIds.size()>0) {
						batchDeleteItems(returned, deleteItemIds);
					}
				}
				if (addItems != null && addItems.size()>0){
					addItems = setAddItemsReturnedId(addItems,returned);
					returnedItemDao.batchInsertReturnedItems(addItems);
				} 	
			    //更新库存表
				List<Inventory> inventories = generateInventoryByReturnedItem(returnedObj,sessionMessage);
				inventoryDao.batchUpdateInventory(inventories);
			    //采购退库，更新零件属性表,更新报价表
				quotationService.handlePartPropertyAndQuotationForReturn(inventories,false);				
				// 客户表里更新客户的应付款 ，应付款=原应付款-退货金额
				Partner partner = (Partner) partnerDao.getById(returned.getPartnerIdByBuyer());
				BigDecimal unpaid = partner.getUnpaid();
				if(unpaid == null){
					unpaid = new BigDecimal(0);
				}
				partner.setUnpaid(unpaid.subtract(returned.getAmount()));
				partnerDao.updatePartnerAmountById(partner);
				// 生成应付款记录
				Payable payable = createPayable(sessionMessage, returned);
				//页面返回信息
			    response = generateResponse(sessionMessage, returned);				   
				response.put(ConstantUtil.JSON_OF_PAYABLEID, payable.getId());
				response.put(ConstantUtil.JSON_OF_CUSTOMERID, payable.getCustomerId());
				return response;
			}
		});	    		
		return  (JSONObject) result;
	}
	/**
	 * 批量删除明细
	 * @param returned
	 * @param deleteItemIds
	 */
	private void batchDeleteItems(Returned returned, List<Integer> deleteItemIds) {
		Map<String,Object> map = new HashMap<String, Object>();
		map.put(ConstantUtil.PARAM_OF_IDS, deleteItemIds);
		map.put(ConstantUtil.PARAM_OF_RETURNEDID, returned.getId());
		returnedItemDao.batchDeleteReturnedItems(map);
	}
	
	/**
	 * 保存payable
	 * @param sessionMessage
	 * @param returned
	 * @return
	 */
	private Payable createPayable(SessionMessage sessionMessage,Returned returned) {
		Payable payable =new Payable();
		Integer companyId = sessionMessage.getCompanyId();
		String code = codeGenericDao.getNewCode(companyId, CodeGeneric.PAYABLE);//应付款凭证号
		payable.setCode(code);
		payable.setCompanyId(companyId);
		payable.setCustomerId(returned.getPartnerIdByBuyer());
		payable.setDocumentType(Inventory.DDOCUMENT_TYPE_RETURNED);
		payable.setDocumentId(returned.getId());
		payable.setDocumentCode(returned.getCodeOfBuyer());
		payable.setPayable(returned.getAmount());
		payable.setCurrentorId(sessionMessage.getUserId());
		payable.setStatus(0);
		//payable.setGmtCreate(new Date());
		payable.setPaid(new BigDecimal(0));
		payableDao.createPayable(payable);
		return payable;
	}
	/**
	 * 返回json字符串:{'returned':{xxxxx},'returnedItems':[{xxxx},{xxxx}....],'buttons':{'isOwner':true/false,'buttons':{xxxx}}}
	 * 
	 * @param sessionMessage
	 * @param returned
	 * @param result
	 * @return {'returned':{xxxxx},'returnedItems':[{xxxx},{xxxx}....],'buttons':{'isOwner':true/false,'buttons':{xxxx}}}
	 */
	private JSONObject generateResponse(SessionMessage sessionMessage,Returned returned) {
		//获得下一状态的按钮
		JSONObject buttonJO = generateButtonsByStatus(returned.getStatus(), returned.getCurrentorId(), sessionMessage.getUserId());
		//返回主表信息
		Map<String,Object> map = new HashMap<String,Object>();
		map.put(ConstantUtil.PARAM_OF_ID, returned.getId());
		map.put(ConstantUtil.PARAM_OF_VARGROUP, DictionaryEnum.GROUP_RETURNED_STATUS.getGroup());
		ReturnedModel returnedModel = getDao().getReturnedByComplexConditons(map).get(0);
		JSONObject returnedJO = JsonUtil.getJSONObjectFromBean(returnedModel);
		//返回明细信息
		List<Map<String,String>> returnedItems = returnedItemDao.getReturnedItemsByReturnedId(returned.getId());
		JSONArray returnedItemArray = JSONArray.fromObject(returnedItems);
		JSONObject returnedObj = new JSONObject();
		returnedObj.put(ConstantUtil.JSON_OF_MAIN, returnedJO);
		returnedObj.put(ConstantUtil.JSON_OF_DETAILS, returnedItemArray);	    
	    returnedObj.put(ConstantUtil.JSON_OF_BUTTONS, buttonJO);	
	    return returnedObj;		
	}
	/**
	 * 退库单浏览跳转浏览该明细
	 * @param returnedId
	 * @return {'returned':{xxxxx},'returnedItems':[{xxxx},{xxxx}....],'msg':'','buttons':{'isOwner':true/false,'buttons':{xxxx}}}
	 */
	public JSONObject generateReturnedAndItemById(Integer returnedId){
		SessionMessage sessionMessage = UserHolder.getCurrentSessionMessage();
		Returned returned = getReturnedByIdAndOwner(returnedId, sessionMessage, false);
		JSONObject response = generateResponse(sessionMessage, returned);		
		return response;
		
	}
	/**
	 * 新增的退货明细设置returnedId
	 * @param addItems
	 * @param returned
	 * @return
	 */
	private List<ReturnedItem> setAddItemsReturnedId(List<ReturnedItem> addItems, Returned returned) {
		List<ReturnedItem> returnedItems = new ArrayList<ReturnedItem>();
		for(ReturnedItem returnedItem : addItems){
			returnedItem.setReturnedId(returned.getId());
			returnedItems.add(returnedItem);
		}
		return returnedItems;
	}

	/**
	 * 解析退货单明细，设置库存剩余数
	 * @param returnedObj
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private List<Inventory> generateInventoryByReturnedItem(JSONObject returnedObj,SessionMessage sessionMessage){
		//明细
		JSONArray detailsArr = returnedObj.getJSONArray(ConstantUtil.JSON_OF_DETAILS);
		List<ReturnedItem> returnedItems = (List<ReturnedItem>) JSONArray.toCollection(detailsArr, ReturnedItem.class);
		List<Inventory> inventories = new ArrayList<Inventory>();
		for(ReturnedItem returnedItem : returnedItems){
			Inventory inventory =  inventoryDao.getInventoryByIdAndCompanyId(returnedItem.getSourceInventoryId(),sessionMessage.getCompanyId(),true);
			Integer onHand = inventory.getOnHand()-returnedItem.getQuantity();
			if(onHand < 0){
				throw new BizException(InventoryErrorEnum.INVENTORY_ON_HAND_ERROR);
			}
			inventory.setOnHand(onHand);
			inventory.setChangeQuantity(returnedItem.getQuantity());
			inventories.add(inventory);
		}
		return inventories;
		
	}
	
    /**
     * 解析成明细表
     * @param returnedObj
     * @return
     */
	@SuppressWarnings("unchecked")
	private Map<String,Object> generateReturnedItem(JSONObject returnedObj) {
		//明细
		JSONArray detailsArr = returnedObj.getJSONArray(ConstantUtil.JSON_OF_DETAILS);
		//新增明细
		List<ReturnedItem> addItems = new ArrayList<ReturnedItem>();
		//修改明细
		List<ReturnedItem> modifyItems = new ArrayList<ReturnedItem>();		
		//总退货成本
		BigDecimal totalAmount = new BigDecimal(0);
		List<ReturnedItem> returnedItems = (List<ReturnedItem>) JSONArray.toCollection(detailsArr, ReturnedItem.class);
		if(returnedItems != null && returnedItems.size()>0){
			for(ReturnedItem returnedItem:returnedItems){
				if(returnedItem.getId()==null){	
					BigDecimal costAmount = returnedItem.getCost().multiply(new BigDecimal(returnedItem.getQuantity()));
					returnedItem.setCostAmount(costAmount);
					totalAmount = totalAmount.add(costAmount);
					addItems.add(returnedItem);
				}else{
					BigDecimal costAmount = returnedItem.getCost().multiply(new BigDecimal(returnedItem.getQuantity()));
					returnedItem.setCostAmount(costAmount);
					totalAmount = totalAmount.add(costAmount);
					modifyItems.add(returnedItem);
				}
			}
		}
		Map<String,Object> map =new HashMap<String,Object>();
		map.put(ConstantUtil.KEY_OF_ADDITEMS, addItems);
		map.put(ConstantUtil.KEY_OF_MODIFYITEMS,modifyItems);	
		map.put(ConstantUtil.KEY_OF_AMOUNT, totalAmount);
		return map;
		
	}
	
	
    /**
     * 解析城主表
     * @param returnedObj
     * @return
     */
	@SuppressWarnings("unchecked")
	private Returned generateReturned(JSONObject returnedObj) {
		SessionMessage sessionMessage =UserHolder.getCurrentSessionMessage();
		//主表
		JSONObject mainObj = returnedObj.getJSONObject(ConstantUtil.JSON_OF_MAIN);		
		for(Iterator it=mainObj.keys();it.hasNext();){
			Object key = it.next();
			Object value = mainObj.get(key);	
			try {
				Field field = Returned.class.getDeclaredField(key.toString());				
				Class type = field.getType();
				if(Date.class.isAssignableFrom(type)&& StringUtils.isBlank(value.toString())){
					mainObj.element(key.toString(), JSONNull.getInstance());
				}
			} catch (Exception e) {
				mainObj.element(key.toString(), "");
			}
		}
		/*String[] dateFormats = new String[] {"yyyy/MM/dd"};   
		JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(dateFormats));*/  
		Returned returned = (Returned) JSONObject.toBean(mainObj,Returned.class);
		if (returned.getId() == null) {
			returned.setBuyerId(sessionMessage.getCompanyId());
		}else{
			Returned returned2 = getReturnedByIdAndOwner(returned.getId(), sessionMessage, false);
			BeanUtils.copyProperties(returned2, returned, new String[]{"sellerId","partnerIdByBuyer","memo","areaId","province","city","district","street","postCode","receiverName","phone","mobile","transportType"});
		}
		return returned;
	}
	
	/**
	 * 根据id,buyerId查找Returned
	 * @param id
	 * @param sessionMessage
	 * @param update，是否select for update
	 * @return Returned
	 */
	public Returned getReturnedByIdAndOwner(Integer id,SessionMessage sessionMessage,boolean update){
		Map<String,Object> map = new HashMap<String, Object>();
		map.put(ConstantUtil.PARAM_OF_ID, id);
		map.put(ConstantUtil.PARAM_OF_BUYERID, sessionMessage.getCompanyId());
		map.put(ConstantUtil.UPDATE,update);
		return getDao().getReturnedById(map);
	}
	
     /**
      * 解析出被删除明细主键
      * @param returnedObj
      * @return
      */
	@SuppressWarnings("unchecked")
	private List<Integer> generateDeleteItemIds(JSONObject returnedObj){
		// 被删除的记录的ID
		JSONArray deleteItemsIds = returnedObj.getJSONArray(ConstantUtil.KEY_OF_DELETEITEMIDS);
		List<Integer> deleteIds = new ArrayList<Integer>();
		if (deleteItemsIds != null && deleteItemsIds.size()>0) {
			deleteIds = (List) JSONArray.toCollection(deleteItemsIds);		
		}
		return deleteIds;
		
	}
	
	/**
	 * 接手或释放单据后加载新的按钮
	 * @param returnedId
	 * @param type
	 * @return  {"isOwner":xxxxx,"buttons":[{xxxx},{xxxx}...],'success':true}
	 */
	public JSONObject updateReturnedCurrentorId(final Integer returnedId,final Integer userId) {
		final SessionMessage sessionMessage = UserHolder.getCurrentSessionMessage();
		Object result = transactionTemplate.execute(new TransactionCallback() {					
			@Override
			public Object doInTransaction(TransactionStatus status) {
				Returned returned = getReturnedByIdAndOwner(returnedId, sessionMessage, true);
				returned.setCurrentorId(userId);
				getDao().update(returned);				
				JSONObject buttonObj = generateButtonsByStatus(returned.getStatus(), returned.getCurrentorId(), sessionMessage.getUserId());
				buttonObj.put(ConstantUtil.SUCCESS, true);
				return buttonObj;
			}
		});	
		return (JSONObject) result;
		
	}
	/**
	 * 待仓库确认状态退回草稿状态
	 * @param returnedId
	 * @return {'success':true,'returnedObject':{'returned':{xxxxx},'returnedItems':[{xxxx},{xxxx}....],'msg':{'confirm'/'alert':xxxxx},'buttons':{'isOwner':true/false,'buttons':{xxxx}}}}
	 */
	public JSONObject updateReturnedStatusById(final Integer returnedId) {	
		final SessionMessage sessionMessage = UserHolder.getCurrentSessionMessage();
		Object result = transactionTemplate.execute(new TransactionCallback() {			
			@Override
			public Object doInTransaction(TransactionStatus status) {
				Returned returned = getReturnedByIdAndOwner(returnedId, sessionMessage, true);
                JSONObject response = checkCurrentorBeforeUpdate(sessionMessage, returned);
                if(response != null){
					return response;
				}else{
                   returned.setStatus(Returned.STATUS_DRAFT);
				   returned.setSubmitter(null);
				   returned.setGmtSubmit(null);
				   getDao().update(returned);
				   JSONObject resp = generateReturnedAndItemById(returnedId);
				   resp.put(ConstantUtil.MSG,ConstantUtil.BACK_TO_DRAFT_SUCCESS);
				   resp.put(ConstantUtil.SUCCESS, true);
				   return resp; 
			    }
            }
		});
		return (JSONObject) result;
		 
	}
	
	/**
	 * 浏览退货单
	 * @param queryMap
	 * @param returnedListModel
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public ListModel getReturnedListModelByConditions(Map queryMap,ListModel returnedListModel) {
		queryMap.put(ConstantUtil.PARAM_OF_VARGROUP, DictionaryEnum.GROUP_RETURNED_STATUS.getGroup());
		queryMap.put(ConstantUtil.PARAM_OF_COMPANYID, UserHolder.getCurrentSessionMessage().getCompanyId());
		returnedListModel.setTotal(getDao().getReturnedCountByComplexConditons(queryMap));
		if(returnedListModel.getOrderBy()==null){
			returnedListModel.setOrderBy(ConstantUtil.ORDERBY_GMTCREATE);
		}
		queryMap.put(ConstantUtil.PARAM_OF_LISTMODEL, returnedListModel);
		List<ReturnedModel> returnedList = getDao().getReturnedByComplexConditons(queryMap);
		returnedListModel.setResult(returnedList);
		return returnedListModel;
	}
	/**
	 * 退货单明细浏览
	 * @param queryMap
	 * @param returnedListModel
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public ListModel getRerurnedItemByConditions(Map queryMap,ListModel returnedListModel) {
		queryMap.put(ConstantUtil.PARAM_OF_COMPANYID, UserHolder.getCurrentSessionMessage().getCompanyId());
	    returnedListModel.setTotal(returnedItemDao.getReturnedItemCountByConditions(queryMap));
	    if(returnedListModel.getOrderBy()==null){
			returnedListModel.setOrderBy(ConstantUtil.ORDERBY_CODEOFBUYER);
		}
	    queryMap.put(ConstantUtil.PARAM_OF_LISTMODEL, returnedListModel);
	    List<Map> returnedItemList = returnedItemDao.getReturnedItemByConditions(queryMap);
		returnedListModel.setResult(returnedItemList);
		return returnedListModel;
	}
	/**
	 * 退库单保存、提交、退库前判断当前处理者是否为单据所有者
	 * @param sessionMessage
	 * @param returned
	 * @return {"success":false,"msg":"xxxxx"}
	 */
	private JSONObject checkCurrentorBeforeUpdate(SessionMessage sessionMessage,Returned returned) {
		Integer currentorId = returned.getCurrentorId();
		Integer userId =sessionMessage.getUserId();
		JSONObject jo = new JSONObject();
		String msg;	
		if(returned.getStatus().equals(Returned.STATUS_RETURNED) && returned.getDepositer() != null){
			String depositorName = ((User)userDao.getById(returned.getDepositer())).getName();
			msg = ConstantUtil.MSG_AHEAD+depositorName+ConstantUtil.MSG_HAS_RETURNED;
			jo.put(ConstantUtil.MSG, msg);
			jo.put(ConstantUtil.SUCCESS, false);
			return jo;
		}
		if(currentorId != null&& !currentorId.equals(userId)){
			String currentorName = ((User)userDao.getById(currentorId)).getName();
			msg = ConstantUtil.MSG_AHEAD+currentorName+ConstantUtil.MSG_ENDING_NOT;			
			jo.put(ConstantUtil.MSG, msg);
			jo.put(ConstantUtil.SUCCESS, false);
			return jo;
		}
		return null;
	}
	/**
	 * 根据id删除处于草稿状态的退库单
	 * @param id
	 * @return {"success":false/true,"msg":"xxxxx"}
	 */
    public JSONObject deleteReturnedByIdAndBuyerId(Integer id) {
    	SessionMessage sessionMessage = UserHolder.getCurrentSessionMessage();
		Returned returned = getReturnedByIdAndOwner(id, sessionMessage, false);
		JSONObject response = checkCurrentorBeforeUpdate(sessionMessage, returned);
		if(response != null){
			return response;
		}
		Map<String,Object> map = new HashMap<String, Object>();
		map.put(ConstantUtil.PARAM_OF_ID, id);
		map.put(ConstantUtil.PARAM_OF_BUYERID, sessionMessage.getCompanyId());
		boolean success = deleteReturnedByCondition(map);
		JSONObject resp = new JSONObject();
		if(!success){
			resp.put(ConstantUtil.SUCCESS, false);
			resp.put(ConstantUtil.MSG, ConstantUtil.MSG_DRAFT_NOT_EXIST);
		}else{
			resp.put(ConstantUtil.SUCCESS, true);
			resp.put(ConstantUtil.MSG, ConstantUtil.MSG_DELETE_DRAFT_SUCCESS);
		}
		return resp;
		
	}
    private void setReturnedAtDeposite(final SessionMessage sessionMessage,Returned returned, BigDecimal amount) {
		returned.setAmount(amount);
		returned.setStatus(Returned.STATUS_RETURNED);
		returned.setDepositer(sessionMessage.getUserId());
		//returned.setGmtDepositer(new Date());
		if(returned.getSubmitter() == null){
			returned.setSubmitter(sessionMessage.getUserId());		    	
		}
		returned.setCurrentorId(null);
	}
    
    
    /**
     * 根据条件删除Returned
     * @param map
     * @return
     */
    @SuppressWarnings("unchecked")
	public boolean deleteReturnedByCondition(Map map){    	
    	return getDao().deleteById(map);
    }
	
    private void insertReturned(SessionMessage sessionMessage,Returned returned) {
		String codeOfBuyer = codeGenericDao.getNewCode(sessionMessage.getCompanyId(), CodeGeneric.RETURNED);
		returned.setCodeOfBuyer(codeOfBuyer);			    	
		returned.setCreatorId(sessionMessage.getUserId());
		returned.setCurrentorId(sessionMessage.getUserId());	
		getDao().create(returned);
	}

	public void setReturnedItemDao(IReturnedItemDao returnedItemDao) {
		this.returnedItemDao = returnedItemDao;
	}

	public void setCodeGenericDao(ICodeGenericDao codeGenericDao) {
		this.codeGenericDao = codeGenericDao;
	}

	public void setInventoryDao(IInventoryDao inventoryDao) {
		this.inventoryDao = inventoryDao;
	}

	public void setPartnerDao(IPartnerDao partnerDao) {
		this.partnerDao = partnerDao;
	}

	public void setPayableDao(IPayableDao payableDao) {
		this.payableDao = payableDao;
	}

	public void setUserDao(IUserDao userDao) {
		this.userDao = userDao;
	}

	public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
		this.transactionTemplate = transactionTemplate;
	}

	public void setQuotationService(QuotationService quotationService) {
		this.quotationService = quotationService;
	}
		
}
